#pragma once

#include <cstdio>
#include <iostream>
#include <time.h>
#include <string>
#include <unistd.h>
#include <stdarg.h>
#include <pthread.h>
#include "LockGuard.hpp"

//日志等级
enum
{
    DEBUG = 0,
    INFO,
    WORING,
    ERROR,
    FATA
};

pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
bool issave = false;
const char *file = "log.txt";

void openSaveMode()
{
    issave = true;
}

void clossSaveMode()
{
    issave = false;
}


// 文件 行 年月日 时分秒 pid 可变参数列表

//将时间转换为string
std::string get_time()
{
    time_t now_time = time(nullptr);
    struct tm *time_struct = localtime(&now_time);
    char t[1024] = {0};
    snprintf(t, sizeof(t), "%d/%d/%d %02d:%02d:%02d",
             time_struct->tm_year + 1900, time_struct->tm_mon + 1, time_struct->tm_mday,
             time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);

    return t;
}

//将日志等级转换为string
std::string level_to_string(int level)
{
    switch (level)
    {
    case 0:
        return "DEBUG";
    case 1:
        return "INFO";
    case 2:
        return "WORING";
    case 3:
        return "ERROR";
    case 4:
        return "FATA";
    default:
        return "UNKOWN";
    }
}

void save_log_massgae(std::string logmassage)
{
    FILE *fp = fopen("log.txt", "a");
    if (fp)
    {
        fseek(fp, 0, SEEK_END);
        fprintf(fp, "%s", logmassage.c_str());
        fclose(fp);
    }
}

void LogMassage(const char *filename, const int line, int level, const char *format, ...)
{
    std::string now_time = get_time();

    //获取可变参数列表的内容
    char va[1024] = {0};
    va_list ap;
    va_start(ap, format);
    vsnprintf(va, sizeof(va), format, ap);
    va_end(ap);

    LockGuard lock(g_mutex);
    std::string logMassage = "[" + level_to_string(level) + "]" + 
                             "[" + filename + "]" + "[" + std::to_string(line) + "]" + "[pid:" + std::to_string(getpid()) + "]" + 
                             "[" + now_time + "]" + "[" + va + "]" + "\n";

    //如果保存模式打开，就将日志输出到文件中
    if (issave)
        save_log_massgae(logMassage);
    else
        std::cout << logMassage << std::endl;
}

//宏替换
#define LOG(level, format, ...)                                       \
    do                                                                \
    {                                                                 \
        LogMassage(__FILE__, __LINE__, level, format, ##__VA_ARGS__); \
    } while (0)